package com.github.maojx0630.translate.translate.dict;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.github.maojx0630.translate.TranslateConfig;

import java.lang.reflect.Field;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author 毛家兴
 * @since 2024-06-19 14:31
 */
public class DictHandleImpl implements DictTranslateHandle {

    private static final Map<String, List<String>> ALIAS_CACHE = new ConcurrentHashMap<>();
    private final ValueCache valueCache;
    private final TranslateConfig config;
    private final Map<String, TranslateConfig.AliasConfig> tableAliasCache = new HashMap<>();

    public DictHandleImpl(ValueCache valueCache, TranslateConfig config) {
        this.config = config;
        this.valueCache = valueCache;
        if (config.getTableConfig().isTableIgnoreCase()) {
            config.getTableConfig().getOtherAliasConfig().forEach((k, v) -> {
                tableAliasCache.put(k.toUpperCase(), v);
            });
        } else {
            tableAliasCache.putAll(config.getTableConfig().getOtherAliasConfig());
        }
    }

    @Override
    public Object getTranslateValue(TranslateField ann, String value, Field field) {
        return valueCache.get(value, ann);
    }

    @Override
    public List<String> getTranslateField(TranslateField translateField, String s, Field field) {
        String name = field.toGenericString();
        List<String> stringList = ALIAS_CACHE.get(name);
        if (CollUtil.isNotEmpty(stringList)) {
            return stringList;
        }
        List<String> list = new ArrayList<>(Arrays.asList(translateField.alias()));
        for (String alias : translateField.suffix()) {
            list.add(field.getName() + alias);
        }
        for (String alias : translateField.prefix()) {
            list.add(alias + field.getName());
        }
        if (CollUtil.isEmpty(list)) {
            if (StrUtil.isBlank(translateField.tableName())) {
                TranslateConfig.DictConfig dict = config.getDictConfig();
                TranslateConfig.AliasConfig aliasConfig = dict.getAliasConfig();
                setAlias(list, field.getName(), aliasConfig);
            } else {
                TranslateConfig.TableConfig table = config.getTableConfig();
                TranslateConfig.AliasConfig aliasConfig = table.getAliasConfig();
                String tableName;
                if (table.isTableIgnoreCase()) {
                    tableName = translateField.tableName().toUpperCase();
                } else {
                    tableName = translateField.tableName();
                }
                TranslateConfig.AliasConfig cache = tableAliasCache.get(tableName);
                if (cache != null) {
                    aliasConfig = cache;
                }
                setAlias(list, field.getName(), aliasConfig);
            }
        }
        if (CollUtil.isEmpty(list)) {
            list.add(field.getName());
        }
        ALIAS_CACHE.put(name, list);
        return list;
    }

    @Override
    public Class<TranslateField> getAnnClass() {
        return TranslateField.class;
    }

    private void setAlias(List<String> list, String fieldName, TranslateConfig.AliasConfig aliasConfig) {
        if (aliasConfig == null) {
            return;
        }
        switch (aliasConfig.getAliasType()) {
            case PREFIX:
                list.add(aliasConfig.getAliasValue() + fieldName);
                break;
            case SUFFIX:
                list.add(fieldName + aliasConfig.getAliasValue());
                break;
            case SELF:
                list.add(fieldName);
                break;
            case OTHER:
                list.add(aliasConfig.getAliasValue());
                break;
        }
    }
}
